package info.hexin.img;

import info.hexin.img.font.FontManager;
import info.hexin.img.font.FontType;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by infi.he on 2016/2/15.
 */
public class TestImgCreate {
    static Map<String, String> priceMap = new HashMap<>();


    public static void main(String[] args) throws Exception {

        String[] typeAs = {"a0101"};
        String[] typeBs = {"b0101"};
        String[] typeCs = {"c0102"};

        addPrice(priceMap);

        for (Map.Entry<String, String> stringStringEntry : priceMap.entrySet()) {
            String id = stringStringEntry.getKey();
            String price = stringStringEntry.getValue();
            String destjpgPath = "E:\\tmp\\img\\destjpg\\" + id;
            File file1 = new File(destjpgPath);
            if (file1.exists()) {
                file1.delete();
            }
            file1.mkdir();
            String file = "E:\\tmp\\img\\sourcjpg\\" + id + ".jpg";

            crateImgTypeABC(typeAs, typeBs, typeCs, id, price, destjpgPath, file);
        }
    }

    private static void crateImgTypeABC(String[] typeAs, String[] typeBs, String[] typeCs, String id, String price, String destjpgPath, String file) throws IOException {
        String jpgId;
        for (String typeA : typeAs) {
            for (String typeB : typeBs) {
                for (String typeC : typeCs) {
                    jpgId = id + "_" + typeB + "_" + typeC;
                    crateImg(file, destjpgPath + "/" + jpgId, price, null, typeB, typeC, true);

                    jpgId = id + "_" + typeC + "_" + typeB;
                    crateImg(file, destjpgPath + "/" + jpgId, price, null, typeB, typeC, false);

                    jpgId = id + "_" + typeA + "_" + typeC;
                    crateImg(file, destjpgPath + "/" + jpgId, price, typeA, null, typeC, true);

                    jpgId = id + "_" + typeC + "_" + typeA;
                    crateImg(file, destjpgPath + "/" + jpgId, price, typeA, null, typeC, false);
                }
                jpgId = id + "_" + typeA + "_" + typeB;
                crateImg(file, destjpgPath + "/" + jpgId, price, typeA, typeB, null, true);

                jpgId = id + "_" + typeB + "_" + typeA;
                crateImg(file, destjpgPath + "/" + jpgId, price, typeA, typeB, null, false);
            }
        }
    }


    private static void crateImg(String file, String descFile, String price, String typeA, String typeB, String typeC, boolean order) throws IOException {
        descFile = descFile + ".jpg";
        //1. 构造画布
        int width = 600;
        int height = 600;
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = (Graphics2D) bufferedImage.getGraphics();
        graphics2D.setBackground(Color.WHITE);
        graphics2D.clearRect(0, 0, width, height);

        fillLeft400X600Img(graphics2D, file, 100, 0);

        if (typeA != null) { //ab ac ba ca
            if (typeB != null) { //ab ba
                if (order) { //ab
                    Font font = FontManager.getFont(FontType.NewZuricaRegular, 32);
                    graphics2D.setFont(font);
                    int typeAHeight = fillPrice(graphics2D, price, 80, true);
                    fillPostage(graphics2D, typeA, 100 + typeAHeight, true);
                } else { //ba
                    int fillHeight = fillPostage(graphics2D, typeA, 80, true);
                    Font font = FontManager.getFont(FontType.NewZuricaBold, 48);
                    graphics2D.setFont(font);
                    fillPrice(graphics2D, price, fillHeight + 100, true);
                }
            }

            if (typeC != null) { //ac ca
                if (order) {
                    int fillHeight = fillPostage(graphics2D, typeC, 80, true);
                    fillPostage(graphics2D, typeA, 100 + fillHeight, true);
                } else {
                    int fillHeight = fillPostage(graphics2D, typeA, 80, true);
                    fillPostage(graphics2D, typeC, 100 + fillHeight, true);
                }
            }
        } else { //bc cb
            if (order) { //bc
                int fillHeight = fillPostage(graphics2D, typeC, 80, true);
                Font font = FontManager.getFont(FontType.NewZuricaBold, 48);
                graphics2D.setFont(font);
                fillPrice(graphics2D, price, fillHeight + 100, true);
            } else { //cb
                Font font = FontManager.getFont(FontType.NewZuricaRegular, 32);
                graphics2D.setFont(font);
                int typeAHeight = fillPrice(graphics2D, price, 80, true);
                fillPostage(graphics2D, typeC, 100 + typeAHeight, true);
            }
        }
        graphics2D.dispose();
        ImageIO.write(bufferedImage, "jpg", new File(descFile));
    }

    private static int fillPrice(Graphics2D graphics2D, String price, int y, boolean distanceBottom) {
        FontMetrics fontMetrics = graphics2D.getFontMetrics();
        int ascent = fontMetrics.getAscent();
        int descent = fontMetrics.getDescent();
        int tmpY = descent / 2;// 由于j g等下面存在高度，价格不会下去，这样行距小点
        int priceWidth = fontMetrics.stringWidth(price);

        int startX = 400 + (200 - priceWidth) / 2;
        int startY;
        if (distanceBottom) {
            startY = 600 - y - tmpY;
        } else {
            startY = y;
        }

        //文本抗锯齿提示值——文本呈现需要使用字体资源中的信息，这些信息指定了每个点大小是否适合应用
        graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        //字体小数规格提示值——用子像素精确度定位字符字形。
        graphics2D.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);

        graphics2D.setColor(new Color(51, 51, 51));
        graphics2D.drawString(price, startX, startY);
        return ascent - tmpY;
    }

    private static void createTypeC(Graphics2D graphics2D, String postageTop, String postageBottom) throws IOException {
        fillPostage(graphics2D, postageTop, 20, false);
        fillPostage(graphics2D, postageBottom, 100, true);
    }

    /**
     * 填充小图片
     *
     * @param graphics2D
     * @throws IOException
     */
    private static int fillPostage(Graphics2D graphics2D, String postage, int y, boolean distanceBottom) throws IOException {
        InputStream postageInput = TestImgCreate.class.getResourceAsStream("/logos/" + postage + ".png");
        BufferedImage read = ImageIO.read(postageInput);
        int width = read.getWidth();
        //计算居中
        int startX = 400 + (200 - width) / 2;
        int height = read.getHeight();
        if (distanceBottom) {
            int startY = 600 - y - height;
            graphics2D.drawImage(read, startX, startY, null);
        } else {
            graphics2D.drawImage(read, startX, y, null);
        }
        return height;
    }


    /**
     * 填充左边400X600图片，填充图片从sourceStartX和sourceStartY进行裁剪400*600
     *
     * @param graphics2D
     * @param file
     * @param sourceStartX
     * @param sourceStartY
     * @throws IOException
     */
    private static void fillLeft400X600Img(Graphics2D graphics2D, String file, int sourceStartX, int sourceStartY) throws IOException {
        ImageInputStream iis = new FileImageInputStream(new File(file));

        //文件读取器
        Iterator readers = ImageIO.getImageReaders(iis);
        ImageReader reader = (ImageReader) readers.next();

        reader.setInput(iis, true);
        ImageReadParam param = reader.getDefaultReadParam();
        // 100，0是左上起始位置，400就是取宽度为400的，就是从100开始取500宽，就是横向100~500，高度600
        param.setSourceRegion(new Rectangle(sourceStartX, sourceStartY, 400, 600));
        BufferedImage read = reader.read(0, param); //将裁剪的图片缓存起来，准备写入大文件中
        int width = read.getWidth(), startTmpX = 0;
        int height = read.getHeight(), startTmpY = 0;
        if (width < 398) {
            startTmpX = (400 - width) / 2;
        }
        if (height < 598) {
            startTmpY = (600 - height) / 2;
        }
        graphics2D.drawImage(read, startTmpX, startTmpY, null);
    }

    private static void addPrice(Map<String, String> priceMap) {
        priceMap.put("716", "$54.99");
        priceMap.put("10316", "$88.99");
        priceMap.put("5475", "$79.99");
        priceMap.put("11897", "$119.99");
        priceMap.put("5478", "$79.99");
        priceMap.put("13055", "$79.99");
        priceMap.put("2120", "$64.99");
        priceMap.put("15334", "$68.00");
        priceMap.put("22780", "$96.00");
        priceMap.put("6289", "$85.99");
        priceMap.put("5454", "$84.99");
        priceMap.put("5448", "$84.99");
        priceMap.put("13391", "$99.99");
        priceMap.put("15968", "$70.00");
        priceMap.put("642", "$74.99");
        priceMap.put("16665", "$88.00");
        priceMap.put("2649", "$64.99");
        priceMap.put("21141", "$68.00");
        priceMap.put("4492", "$94.99");
        priceMap.put("9726", "$158.99");
    }
}
